/*
 * Copyright 2022-2029 heshuixing(https://gitee.com/heshuixing)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mercury.ec.framework.air.core.client.impl.sunstn.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.mercury.ec.framework.air.core.client.dto.order.create.AirOrderPassengerCreateReqDTO;
import com.mercury.ec.framework.air.core.client.dto.order.create.AirOrderRouteCreateReqDTO;
import com.mercury.ec.framework.air.core.client.dto.search.patex.AirPatexRouteReqDTO;
import com.mercury.ec.framework.air.core.client.dto.search.rt.AirRtPassengerRespDTO;
import com.mercury.ec.framework.air.core.client.dto.search.rt.AirRtRespDTO;
import com.mercury.ec.framework.air.core.client.dto.search.rtkt.AirRtktRespDTO;
import com.mercury.ec.framework.air.core.client.dto.search.xsfsi.AirXsfsiRouteReqDTO;
import com.mercury.ec.framework.common.enums.CardTypeEnum;
import com.mercury.ec.module.basic.controller.admin.airservicefeerule.vo.rulesetting.AirServiceFeeRuleSettingRespVO;
import com.mercury.ec.module.basic.enums.BasicAdditionalTypeEnum;
import com.mercury.ec.module.basic.enums.BasicAirServiceFeeRuleSettingCountTypeEnum;
import com.mercury.ec.module.basic.enums.BasicAirTicketTypeEnum;
import com.mercury.ec.module.basic.enums.BasicPassengerTypeEnum;
import com.mercury.ec.module.system.enums.common.SexEnum;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 新港接口工具类
 *
 * @author hesx
 */
@Slf4j
public class SunstnUtils {

    /**
     * 获取新港SD航班信息<br/>
     * CA8881|Y|CTUPEK|2007-08-12$CA8887|Q|PEKCTU|2 007-08-16
     *
     * @param routes
     * @return
     */
    public static String getSunstnSdAirInfo(List<AirOrderRouteCreateReqDTO> routes) {
        StringBuilder sb = new StringBuilder("");
        for (AirOrderRouteCreateReqDTO route : routes) {
            sb.append("$");
            sb.append(route.getAirlineNo());
            sb.append(route.getFlightNo());
            sb.append("|");
            sb.append(route.getCabin());
            sb.append("|");
            sb.append(route.getDepart());
            sb.append(route.getArrive());
            sb.append("|");
            sb.append(route.getFlightDate().toString());
        }
        String airInfo = sb.substring(1);
        log.info("SUNSTN SD航班信息原文【{}】", airInfo);
        return HexUtil.encodeHexStr(airInfo, Charset.forName("GB18030")); // 16进制编码
    }

    /**
     * 获取新港SD乘客信息<br/>
     * <p>
     * adu(chd,inf)|乘机人 1|ssr foid(ssr docs)指令行|手机号码
     * $chdy|儿童 1| ssr foid(ssr docs)指令行|手机号码|生日
     * 说明:每个乘客以字符“$”间隔，每个乘机人的信息以
     * 10
     * “|”间隔，每个乘机人的项目顺序不能改变（adu:成人
     * chdY|F|C:儿童 inf:婴儿）
     * </p>
     *
     * <p>
     * adu|邓禄勇|SSR FOID YY HK/NI510230197903174978|13996136910$adu|王尧|SSR DOCS CZ HK1 P/CHN/EG7742872/CHN/12MAY00/M/10JUL19/WANG/YAO
     * </p>
     *
     * @param passengers
     * @param routes
     * @return
     */
    public static String getSunstnSdSsrInfo(List<AirOrderPassengerCreateReqDTO> passengers, List<AirOrderRouteCreateReqDTO> routes) {
        StringBuilder sb = new StringBuilder("");
        for (AirOrderPassengerCreateReqDTO passenger : passengers) {
            sb.append("$");
            sb.append(getSunstnPassengerType(passenger.getType()));
            sb.append("|");
            sb.append(passenger.getName());
            sb.append("|");
            if ("NI".equals(getSunstnCardType(passenger.getCardType()))) {
                // 身份证
                sb.append("SSR FOID");
                sb.append(" " + routes.get(0).getAirlineNo() + " ");
                sb.append("HK");
                sb.append("/NI");
                sb.append(passenger.getCardNo());
                sb.append("|");
                sb.append(passenger.getMobile());
            } else {
                sb.append("SSR DOCS");
                sb.append(" " + routes.get(0).getAirlineNo() + " ");
                sb.append("HK1 ");
                sb.append(getSunstnCardType(passenger.getCardType()));
                sb.append("/");
                sb.append(passenger.getCardIssuingCountryNo());
                sb.append("/");
                sb.append(passenger.getCardNo());
                sb.append("/");
                sb.append(passenger.getCountryNo());
                sb.append("/");
                sb.append(getSunstnDate(passenger.getBirthday()));
                sb.append("/");
                sb.append(getSunstnSex(passenger.getSex()));
                sb.append("/");
                sb.append(getSunstnDate(passenger.getCardValidDate()));
                sb.append("/");
                sb.append(passenger.getName());
                sb.append("|");
                sb.append(passenger.getMobile());
            }
        }
        String ssrInfo = sb.substring(1);
        log.info("SUNSTN SD乘客信息原文【{}】", ssrInfo);
        return HexUtil.encodeHexStr(ssrInfo, Charset.forName("GB18030")); // 16进制编码
    }

    /**
     * 获取新港乘客类型
     *
     * @param passengerType
     * @return
     */
    public static String getSunstnPassengerType(Integer passengerType) {
        switch (BasicPassengerTypeEnum.getByType(passengerType)) {
            case ADULT:
                return "adu";
            case CHILD:
                return "chdY";
            case BABY:
                return "inf";
        }
        return "adu";
    }

    /**
     * 获取新港证件类型
     *
     * @param cardType
     * @return
     */
    public static String getSunstnCardType(Integer cardType) {
        if (cardType != null) {
            switch (CardTypeEnum.getByType(cardType)) {
                case IDCARD:
                case GATJMJZZ:
                    return "NI";
                case PASSPORT:
                    return "P";
                case ARMYMANCARD:
                    return "M";
                case HYZ:
                    return "G";
                case GATXZ:
                case TWTXZ:
                case GAJMLWNDTXZ:
                case TWJMLWDLTXZ:
                    return "A";
                case OTHER:
                    return "I";
                case FOREIGN:
                    return "F";
            }
        }
        return "NI";
    }

    /**
     * 获取新港xsfsi运价航段信息<br/>
     * <p>
     * CA8881|Y|CTUPEK|2012-06-24 12:30|2012-06-24 12:30$CA8887|Q|PEKCTU|2012-06-24 12:30|2012-06-24 12:30
     *
     * @param routes
     * @return
     */
    public static String getSunstnXsfsiVoyage(List<AirXsfsiRouteReqDTO> routes) {
        StringBuilder sb = new StringBuilder("");
        for (AirXsfsiRouteReqDTO route : routes) {
            sb.append("$");
            sb.append(route.getAirlineNo());
            sb.append(route.getFlightNo());
            sb.append("|");
            sb.append(route.getCabin());
            sb.append("|");
            sb.append(route.getDepart());
            sb.append(route.getArrive());
            sb.append("|");
            sb.append(route.getFlightDate().toString());
            sb.append(" ");
            sb.append(route.getDepartTime());
            sb.append(route.getFlightDate().toString());
            sb.append(" ");
            sb.append(route.getArriveTime());
        }
        return HexUtil.encodeHexStr(sb.substring(1), Charset.forName("GB18030")); // 16进制编码
    }

    /**
     * 转换新港PATEX接口的航段信息<hr/>
     * <p>
     * CA8881|Y|CTUPEK|2007-08-12$CA8887|Q|PEKCTU|2007-08-16
     *
     * @param routes
     * @return
     */
    public static String getSunstnPatexAirInfo(List<AirPatexRouteReqDTO> routes) {
        StringBuilder sb = new StringBuilder("");
        for (AirPatexRouteReqDTO route : routes) {
            sb.append("$");
            sb.append(route.getAirlineNo());
            sb.append(route.getFlightNo());
            sb.append("|");
            sb.append(route.getCabin());
            sb.append("|");
            sb.append(route.getDepart());
            sb.append(route.getArrive());
            sb.append("|");
            sb.append(route.getFlightDate().toString());
        }
        return HexUtil.encodeHexStr(sb.substring(1), Charset.forName("GB18030")); // 16进制编码
    }

    /**
     * 解析RMK客户编号
     *
     * @param remark
     * @return
     */
    public static String getCustomerNo(String remark) {
        // RMK CMS/A/** |RMK MP 17779111146 |RMK TJ KHN109|RMK CA/NGN0L3|RMK AUTOMATIC FARE QUOTE |RMK FARECODE/GP/CA8384/HRBPKX/11NOV24/CNY1980.00 |RMK FARECODE/GP/CA8381/PKXJGS/11NOV24/CNY1980.00
        // RMK KH HNDX/0003
        String customerNo = null;
        if (StrUtil.isNotBlank(remark)) {
            String[] rmkArray = remark.split("\\|");
            for (String rmk : rmkArray) {
                if (rmk.contains("RMK KH")) {
                    String[] textArray = rmk.split("/");
                    try {
                        customerNo = textArray[0].split(" ")[2];
                    } catch (Exception e) {
                        log.error("新港回调解析客户编号异常", e);
                    }
                    break;
                }
            }
        }
        return customerNo;
    }

    /**
     * 解析RMK联系人编号
     *
     * @param remark
     * @return
     */
    public static String getContactNo(String remark) {
        // RMK CMS/A/** |RMK MP 17779111146 |RMK TJ KHN109|RMK CA/NGN0L3|RMK AUTOMATIC FARE QUOTE |RMK FARECODE/GP/CA8384/HRBPKX/11NOV24/CNY1980.00 |RMK FARECODE/GP/CA8381/PKXJGS/11NOV24/CNY1980.00
        // RMK KH HNDX/0003
        String contactNo = null;
        if (StrUtil.isNotBlank(remark)) {
            String[] rmkArray = remark.split("\\|");
            for (String rmk : rmkArray) {
                if (rmk.contains("RMK KH")) {
                    String[] textArray = rmk.split("/");
                    try {
                        contactNo = textArray[1];
                    } catch (Exception e) {
                        log.error("新港回调解析联系人编号异常", e);
                    }
                    break;
                }
            }
        }
        return contactNo;
    }

    /**
     * 解析出票office
     *
     * @param remark
     * @return
     */
    public static String getIssueOffice(String remark) {
        // RMK CMS/A/** |RMK MP 17779111146 |RMK TJ KHN109|RMK CA/NGN0L3|RMK AUTOMATIC FARE QUOTE |RMK FARECODE/GP/CA8384/HRBPKX/11NOV24/CNY1980.00 |RMK FARECODE/GP/CA8381/PKXJGS/11NOV24/CNY1980.00
        // RMK TJ KHN109
        String issueOffice = null;
        if (StrUtil.isNotBlank(remark)) {
            String[] rmkArray = remark.split("\\|");
            for (String rmk : rmkArray) {
                if (rmk.contains("RMK TJ")) {
                    String[] textArray = rmk.split(" ");
                    try {
                        issueOffice = textArray[2];
                    } catch (Exception e) {
                        log.error("新港回调解析出票office异常", e);
                    }
                    break;
                }
            }
        }
        return issueOffice;
    }

    /**
     * 计算销售服务费
     *
     * @param airServiceFeeRuleSetting 机票服务费设置
     * @param salePrice                销售价
     * @param passengerType            乘客类型
     * @param routeCount               航段数
     * @return
     */
    public static BigDecimal getSaleServiceFee(AirServiceFeeRuleSettingRespVO airServiceFeeRuleSetting, BigDecimal salePrice, Integer passengerType, int routeCount) {
        if (airServiceFeeRuleSetting == null || salePrice == null || salePrice.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        switch (BasicPassengerTypeEnum.getByType(passengerType)) {
            case ADULT:
                saleServiceFee = airServiceFeeRuleSetting.getSaleAdultServiceFee();
                break;
            case CHILD:
                saleServiceFee = airServiceFeeRuleSetting.getSaleChildServiceFee();
                break;
            case BABY:
                saleServiceFee = airServiceFeeRuleSetting.getSaleBabyServiceFee();
                break;
        }
        switch (BasicAdditionalTypeEnum.getByType(airServiceFeeRuleSetting.getAdditionalType())) {
            case FIXED_AMOUNT:
        }
        if (BasicAdditionalTypeEnum.isSaleRate(airServiceFeeRuleSetting.getAdditionalType())) {
            saleServiceFee = salePrice.multiply(saleServiceFee).divide(BigDecimal.valueOf(100));
        }
        if (BasicAirServiceFeeRuleSettingCountTypeEnum.isByPassengerRoute(airServiceFeeRuleSetting.getCountType())) {
            saleServiceFee = saleServiceFee.multiply(BigDecimal.valueOf(routeCount));
        }
        return saleServiceFee;
    }

    /**
     * 解析航司大编码
     *
     * @param remark
     * @return
     */
    public static String getBigPnr(String remark) {
        // RMK CMS/A/** |RMK MP 17779111146 |RMK TJ KHN109|RMK CA/NGN0L3|RMK AUTOMATIC FARE QUOTE |RMK FARECODE/GP/CA8384/HRBPKX/11NOV24/CNY1980.00 |RMK FARECODE/GP/CA8381/PKXJGS/11NOV24/CNY1980.00
        // RMK CA/PGD3GV
        String bigPnr = null;
        if (StrUtil.isNotBlank(remark)) {
            String[] rmkArray = remark.split("\\|");
            for (String rmk : rmkArray) {
                String pattern = "^RMK [A-Z]{2}/[A-Z0-9]{6}$";
                if (rmk.matches(pattern)) {
                    return rmk;
                }
            }
        }
        return bigPnr;
    }

    /**
     * 解析客户协议号
     *
     * @param remark
     * @return
     */
    public static String getCustomerAgreementNo(String remark) {
        // RMK CMS/A/** |RMK MP 17779111146 |RMK TJ KHN109|RMK CA/NGN0L3|RMK AUTOMATIC FARE QUOTE |RMK FARECODE/GP/CA8384/HRBPKX/11NOV24/CNY1980.00 |RMK FARECODE/GP/CA8381/PKXJGS/11NOV24/CNY1980.00
        // RMK FARECODE/GP/CA8384/HRBPKX/11NOV24/CNY1980.00
        String customerAgreementNo = null;
        if (StrUtil.isNotBlank(remark)) {
            String[] rmkArray = remark.split("\\|");
            for (String rmk : rmkArray) {
                if (rmk.contains("RMK FARECODE")) {
                    String[] textArray = rmk.split(" ");
                    try {
                        String priceStr = textArray[1];
                        String[] priceTextArray = priceStr.split("/");
                        String no = priceTextArray[1];
                        if (!no.contains("GP")) { // 过滤协议号为GP
                            customerAgreementNo = no;
                        }
                    } catch (Exception e) {
                        log.error("新港回调解析客户协议号异常", e);
                    }
                    break;
                }
            }
        }
        return customerAgreementNo;
    }

    /**
     * 根据身份证获取性别
     *
     * @param cardNo
     * @return
     */
    public static Integer getSexByIdCard(String cardNo) {
        if (IdcardUtil.isValidCard(cardNo)) {
            int gender = IdcardUtil.getGenderByIdCard(cardNo);
            switch (gender) {
                case 0:
                    return SexEnum.FEMALE.getSex();
                case 1:
                    return SexEnum.MALE.getSex();
            }
        }
        return null;
    }

    /**
     * 根据身分证号获取生日
     *
     * @param cardNo
     * @return
     */
    public static LocalDate getBirthdayByIdCard(String cardNo) {
        if (IdcardUtil.isValidCard(cardNo)) {
            return LocalDateTimeUtil.parseDate(IdcardUtil.getBirthByIdCard(cardNo), "yyyyMMdd");
        }
        return null;
    }

    /**
     * 获取新港性别
     *
     * @param sex
     * @return
     */
    public static String getSunstnSex(Integer sex) {
        switch (sex) {
            case 1:
                return "M";
            case 2:
                return "F";
            case 0:
                return "U";
        }
        return "M";
    }

    /**
     * 解析新港日期，例：31OCT/OCT31/20MAR80
     *
     * @param sunstnDate
     * @param type       1-生日/2-有效期/3-航班日期
     * @return
     */
    public static LocalDate parseSunstnDate(String sunstnDate, int type) {
        if (StrUtil.isBlank(sunstnDate)) {
            return null;
        }
        int day = 0;
        String airMonth = "";
        String year = "";
        if (Pattern.matches("^[0-9]{2}[A-Za-z]{3}$", sunstnDate)) {
            day = Integer.parseInt(sunstnDate.substring(0, 2));
            airMonth = sunstnDate.substring(2).toUpperCase();
        } else if (Pattern.matches("^[A-Za-z]{3}[0-9]{2}$", sunstnDate)) {
            day = Integer.parseInt(sunstnDate.substring(3));
            airMonth = sunstnDate.substring(0, 3).toUpperCase();
        } else if (Pattern.matches("^[0-9]{2}[A-Za-z]{3}[0-9]{2}$", sunstnDate)) {
            day = Integer.parseInt(sunstnDate.substring(0, 2));
            airMonth = sunstnDate.substring(2, 5).toUpperCase();
            year = sunstnDate.substring(5);
        } else {
            log.error("Invalid date abbreviation: " + sunstnDate);
            return null;
        }
        int month = 0;
        switch (airMonth) {
            case "JAN":
                month = 1;
                break;
            case "FEB":
                month = 2;
                break;
            case "MAR":
                month = 3;
                break;
            case "APR":
                month = 4;
                break;
            case "MAY":
                month = 5;
                break;
            case "JUN":
                month = 6;
                break;
            case "JUL":
                month = 7;
                break;
            case "AUG":
                month = 8;
                break;
            case "SEP":
                month = 9;
                break;
            case "OCT":
                month = 10;
                break;
            case "NOV":
                month = 11;
                break;
            case "DEC":
                month = 12;
                break;
            default:
                throw new IllegalArgumentException("Invalid month abbreviation: " + airMonth);
        }
        if (StrUtil.isBlank(year)) {
            return LocalDate.of(LocalDate.now().getYear(), month, day);
        } else {
            // 1-生日/2-有效期/3-其它
            if (type == 1) {
                String currentYear = LocalDate.now().getYear() + "";
                currentYear = currentYear.substring(2);
                int currentYearInt = Integer.parseInt(currentYear);
                if (currentYearInt > Integer.parseInt(year)) {
                    return LocalDate.of(Integer.parseInt(19 + year), month, day);
                } else {
                    return LocalDate.of(Integer.parseInt(20 + year), month, day);
                }
            } else if (type == 2) {
                return LocalDate.of(Integer.parseInt(20 + year), month, day);
            } else {
                return LocalDate.of(LocalDate.now().getYear(), month, day);
            }
        }
    }

    /**
     * 获取新港日期
     *
     * @param date
     * @return
     */
    public static String getSunstnDate(LocalDate date) {
        if (date == null) {
            return null;
        }
        String year = date.getYear() + "";
        year = year.substring(2);
        int month = date.getMonth().getValue();
        int day = date.getDayOfMonth();
        String airMonth = "";
        switch (month) {
            case 1:
                airMonth = "JAN";
                break;
            case 2:
                airMonth = "FEB";
                break;
            case 3:
                airMonth = "MAR";
                break;
            case 4:
                airMonth = "APR";
                break;
            case 5:
                airMonth = "MAY";
                break;
            case 6:
                airMonth = "JUN";
                break;
            case 7:
                airMonth = "JUL";
                break;
            case 8:
                airMonth = "AUG";
                break;
            case 9:
                airMonth = "SEP";
                break;
            case 10:
                airMonth = "OCT";
                break;
            case 11:
                airMonth = "NOV";
                break;
            case 12:
                airMonth = "DEC";
                break;
            default:
                throw new IllegalArgumentException("Invalid airMonth abbreviation: " + month);
        }
        return day + airMonth + year;
    }

    /**
     * 获取新港自定义行<br/>
     * <p>
     * CTCM项：OSI CA CTCT13800181000
     * </p>
     *
     * @param contactMobile
     * @return
     */
    public static String getSunstnSline(String contactMobile, List<AirOrderRouteCreateReqDTO> routes) {
        StringBuffer sb = new StringBuffer("");
        // CTCM项
        sb.append("OSI");
        sb.append(" " + routes.get(0).getAirlineNo() + " ");
        sb.append("CTCT");
        sb.append(contactMobile);
        return HexUtil.encodeHexStr(sb.toString(), Charset.forName("GB18030"));
    }

    /**
     * 根据原文解析补充信息
     *
     * @param airRtRespDTO
     * @return
     */
    public static void completeRtReulst(AirRtRespDTO airRtRespDTO) {
        String content = airRtRespDTO.getPnrContent();
        // 替换回车换行符
        content = content.replaceAll("\\r", "\n");

        // 解析pnr
        String pnr = getPnr(content);
        log.info("RT解析：pnr【{}】", pnr);

        // 解析office号
        String bookOffice = getBookOffice(content);
        log.info("RT解析：bookOffice【{}】", bookOffice);

        // 解析备注
        String remark = getRmk(content);
        log.info("RT解析：rmk【{}】", remark);

        // 提取航班信息
        List<List<String>> flight = getFlight(content, pnr);
        for (int i = 0; i < flight.size(); i++) {
            log.info("RT解析：航班【{}】", flight.get(i));
        }

        // 提取乘客信息
        List<Map<String, Object>> fare = getFare(content, pnr);
        for (Map<String, Object> map : fare) {
            log.info("RT解析：乘客【{}】", JSONUtil.toJsonStr(map));
        }

        // 补充信息
        airRtRespDTO.setBookOffice(bookOffice);
        // 补充乘客信息
        List<AirRtPassengerRespDTO> passengers = airRtRespDTO.getPassengers();
        Map<String, AirRtPassengerRespDTO> passengerMap = airRtRespDTO.getPassengers().stream().filter(p -> StrUtil.isNotBlank(p.getCardNo())).collect(Collectors.toMap(p -> p.getCardNo(), v -> v, (v1, v2) -> v1));
        for (Map<String, Object> map : fare) {
            if ("0".equals(map.get("ftype"))) {
                // 身份证
                List<String> cardList = (List<String>) map.get("card");
                if (CollUtil.isNotEmpty(cardList)) {
                    AirRtPassengerRespDTO airRtPassengerRespDTO = passengerMap.get(cardList.get(0));
                    if (airRtPassengerRespDTO != null) {
                        airRtPassengerRespDTO.setCountryNo("CN");
                        airRtPassengerRespDTO.setCardIssuingCountryNo("CN");
                    }
                }
            } else if ("2".equals(map.get("ftype"))) {
                // 补充婴儿
                AirRtPassengerRespDTO airRtPassengerRespDTO = new AirRtPassengerRespDTO();
                airRtPassengerRespDTO.setName((String) map.get("name"));
                airRtPassengerRespDTO.setType(BasicPassengerTypeEnum.BABY.getType());
                airRtPassengerRespDTO.setHaveBaby(false);
                airRtPassengerRespDTO.setCountryNo("CN");
                airRtPassengerRespDTO.setCardIssuingCountryNo("CN");
                airRtPassengerRespDTO.setCardType(CardTypeEnum.IDCARD.getType());
                airRtPassengerRespDTO.setCardNo(((List<String>) map.get("card")).get(0));
                airRtPassengerRespDTO.setSex(SexEnum.MALE.getSex()); // 性别默认：男
                airRtPassengerRespDTO.setBirthday(SunstnUtils.parseSunstnDate(airRtPassengerRespDTO.getCardNo(), 1));
                airRtPassengerRespDTO.setCardIssuingCountryNo("CN");
                try {
                    String ticketNo = (String) map.get("no");
                    if (StrUtil.isNotBlank(ticketNo)) {
                        ticketNo = ticketNo.replaceAll("INF", "");
                        airRtPassengerRespDTO.setAirlineIssueNo(ticketNo.substring(0, 3));
                        airRtPassengerRespDTO.setTicketNo(ticketNo.substring(3));
                        airRtPassengerRespDTO.setTicketLastNo(null);
                    }
                } catch (Exception e) {
                    log.error("RT 解析票号异常", e);
                }
                airRtPassengerRespDTO.setMobile((String) map.get("mobile"));
                passengers.add(airRtPassengerRespDTO);
            } else if ("1".equals(map.get("ftype"))) {
                // 其它证件
                List<String> cardList = (List<String>) map.get("card");
                if (CollUtil.isNotEmpty(cardList)) {
                    AirRtPassengerRespDTO airRtPassengerRespDTO = passengerMap.get(cardList.get(2));
                    if (airRtPassengerRespDTO != null) {
                        // card: [证件类型,发证国家,证件号码,国籍,出生日期,性别,证件有效期]
                        airRtPassengerRespDTO.setCardType(getCardType(cardList.get(0)));
                        airRtPassengerRespDTO.setCountryNo(cardList.get(3));
                        airRtPassengerRespDTO.setCardIssuingCountryNo(cardList.get(1));
                        airRtPassengerRespDTO.setBirthday(SunstnUtils.parseSunstnDate(cardList.get(4), 1));
                        airRtPassengerRespDTO.setSex(parseAirSex(cardList.get(5)));
                        airRtPassengerRespDTO.setCardValidDate(SunstnUtils.parseSunstnDate(cardList.get(6), 2));
                    }
                }
            }
        }
    }

    public static int parseAirSex(String sex) {
        if ("M".equals(sex)) {
            return SexEnum.MALE.getSex();
        } else if ("F".equals(sex)) {
            return SexEnum.FEMALE.getSex();
        }
        return SexEnum.UNKNOWN.getSex();
    }

    /**
     * 转换新港证件类型
     * <p>
     * P-护照    M-军官证     G-海员证     A-通行证      F-外国人永久居留证  C-驻华外交人员证   I-其它证件
     * </p>
     *
     * @param sunstnCardType
     * @return
     */
    public static int getCardType(String sunstnCardType) {
        switch (sunstnCardType) {
            case "P":
                return CardTypeEnum.PASSPORT.getType();
            case "M":
                return CardTypeEnum.ARMYMANCARD.getType();
            case "G":
                return CardTypeEnum.HYZ.getType();
            case "A":
                return CardTypeEnum.GATXZ.getType();
            case "F":
                return CardTypeEnum.FOREIGN.getType();
        }
        return CardTypeEnum.OTHER.getType();
    }

    /**
     * 解析pnr
     *
     * @param rtinfo
     * @return
     */
    public static String getPnr(String rtinfo) {
        String[] infoArr = rtinfo.split("\n");
        String pnr = "";
        for (int i = 0; i < infoArr.length; i++) {
            if (Pattern.matches("\\d{4} \\d{4}", infoArr[i])) {
                String[] pnrs = infoArr[i - 1].split(" ");
                for (int j = pnrs.length - 1; j >= 0; j--) {
                    if (pnrs[j].length() == 6) {
                        pnr = pnrs[j];
                        break;
                    }
                }
            }
            if (pnr.length() > 0) {
                break;
            }
        }
        return pnr;
    }

    /**
     * 解析office号
     *
     * @param content
     * @return
     */
    public static String getBookOffice(String content) {
        String office = "";
        String[] officeInfoArr = content.replaceAll("\n", " ").split("\\.");
        String[] officeInfoArr2 = Arrays.stream(officeInfoArr).filter(p -> StrUtil.isNotBlank(p.trim())).collect(Collectors.toList()).toArray(new String[0]);
        String officeStr = officeInfoArr2[officeInfoArr2.length - 1].replaceAll("-", "").replaceAll(" ", "");
        if (officeStr.length() == 6) {
            if (Pattern.matches("^[a-zA-Z]{3}[0-9]{3}$", officeStr)) {
                office = officeStr;
            }
        }
        return office;
    }

    /**
     * 提取备注信息，多备注项用 | 分割
     *
     * @param content
     * @return
     */
    public static String getRmk(String content) {
        String[] itemArray = content.split("\n");
        String[] arr = Arrays.stream(itemArray).filter(p -> StrUtil.isNotBlank(p.trim())).collect(Collectors.toList()).toArray(new String[0]);
        List<String> rmk = new ArrayList<>();
        for (int ri = 0; ri < arr.length; ri++) {
            if (arr[ri].length() > 0 && arr[ri].indexOf(".RMK") > -1) {
                rmk.add("RMK " + arr[ri].split("RMK")[1]);
            }
        }
        if (rmk.size() > 0) {
            return rmk.stream().collect(Collectors.joining("|"));
        } else {
            return "";
        }
    }

    /**
     * 提取航班信息
     * <p>
     * 返回格式：数组<br/>
     * 返回样例：[[MU2409,N,SA07SEP,TYNHET,RR2,1510,1615,E,T2]] 一段行程<br/>
     * 返回样例：[[MU2409,N,SA07SEP,TYNHET,RR2,1510,1615,E,T2],[MU2409,N,SA07SEP,TYNHET,RR2,1510,1615,E,T2]] 两段行程<br/>
     * 字段说明：航班号,仓位,航班日期,出发地三字码+目的地三字码,当前状态,起飞时间,到达时间,机场航站楼<br/>
     * </p>
     *
     * @param content
     * @param pnr
     * @return
     */
    public static List<List<String>> getFlight(String content, String pnr) {
        List<List<String>> fliht = new ArrayList<>();
        int pnrNum = content.split(pnr).length;
        String[] flihtS = content.split(pnr)[1].split("\\.");
        Boolean isGJ = false;
        if (content.indexOf("SSR DOCS") > -1) {
            isGJ = true;
        }
        if (pnrNum > 2) {
            flihtS = content.split(pnr)[2].split("\\.");
        }
        for (int i = 0; i < flihtS.length; i++) {
            String[] tempArray = flihtS[i].replaceAll(" +", " ").split("\n")[0].split(" ");
            String[] itemArray = Arrays.stream(tempArray).filter(p -> StrUtil.isNotBlank(p.trim())).collect(Collectors.toList()).toArray(new String[0]);
            if (itemArray.length > 7) {
                if ((itemArray[0].length() == 6 || itemArray[0].length() == 5) && Pattern.matches("^[a-zA-Z0-9]{2,3}[0-9]{3}$", itemArray[0])) {
                    if (itemArray.length > 9 && isGJ) {
                        fliht.add(Arrays.asList(ArrayUtil.sub(itemArray, 0, 10)));
                    } else {
                        //处理特殊情况，日期和城市在一起
                        if (itemArray[2].length() >= 13) {
                            List<String> tlist = new ArrayList<>();
                            tlist.addAll(Arrays.asList(ArrayUtil.sub(itemArray, 0, 1)));
                            tlist.add(itemArray[2].substring(0, 7));
                            tlist.add(itemArray[2].substring(itemArray[2].length() - 6, itemArray[2].length() - 1));
                            tlist.addAll(Arrays.asList(ArrayUtil.sub(itemArray, 3, 8)));
                            fliht.add(tlist);
                        } else {
                            if (itemArray.length >= 9) {
                                if (itemArray[8].indexOf("--") > -1 && itemArray[8].length() > 2) {
                                    String[] tarr = ArrayUtil.sub(itemArray, 0, 8);
                                    ArrayList<String> tlist = CollUtil.toList(tarr);
                                    tlist.add("".equals(itemArray[8].split("--")[0]) ? "--" : itemArray[8].split("--")[0]);
                                    tlist.add(itemArray[8].split("--").length > 1 ? ("".equals(itemArray[8].split("--")[1]) ? "--" : itemArray[8].split("--")[1]) : "--");
                                    fliht.add(tlist);
                                } else {
                                    fliht.add(Arrays.asList(ArrayUtil.sub(itemArray, 0, 9)));
                                }
                            } else {
                                fliht.add(Arrays.asList(ArrayUtil.sub(itemArray, 0, 8)));
                            }
                        }
                    }
                }
            }
        }
        return fliht;
    }

    /**
     * 提取乘客信息
     * <p>
     * 返回格式：数组 (ftype为类型，0代表身份证1代表其它证件)
     * 返回样例：身份证[{ftype:0, name: 姓名, card: 证件号码, no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税 },{ name: 姓名, card: 证件号码, no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税,mobile:CTCM项 }]
     * 返回样例：其他证件  [{ftype:1, name: 姓名, card: [证件类型,发证国家,证件号码,国籍,出生日期,性别,证件有效期], no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税 },{ name: 姓名, card: 证件号码, no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税,mobile:CTCM项 }]
     * 证件说明：证件类型对照（P-护照    M-军官证     G-海员证     A-通行证      F-外国人永久居留证  C-驻华外交人员证   I-其它证件）
     * 字段说明：票号及票价等可能为空，根据pnr当前状态及信息确定，tax为税（国际票）
     * </p>
     *
     * @param pnrContent
     * @param pnr
     * @return
     */
    public static List<Map<String, Object>> getFare(String pnrContent, String pnr) {
        // 提取乘客、证件
        List<Map<String, String>> fName = new ArrayList<>();
        List<Map<String, Object>> fCard = new ArrayList<>();
        List<Map<String, String>> fTno = new ArrayList<>();
        List<Map<String, String>> price = new ArrayList<>();
        List<Map<String, Object>> fare = new ArrayList<>();
        List<Map<String, String>> ctcm = new ArrayList<>();
        List<Map<String, Object>> fGJ = new ArrayList<>();
        int fNum = 1;
        boolean isGJ = false;
        boolean isINF = false;
        String[] infoArr = null;
        if (pnrContent.split("1\\.")[1].split("\n")[0].indexOf(pnr) > -1) {
            infoArr = ("1." + pnrContent.split("1\\.")[1].split("\n")[0].split(pnr)[0]).split("\\.");
            if (pnrContent.split("1\\.")[1].split("\n")[0].indexOf(pnr) == -1) {
                infoArr = ("1." + pnrContent.split("1\\.")[1].split("\n")[0]).split("\\.");
            }
        } else {
            infoArr = pnrContent.split(pnr)[0].replace("\n", "").split("\\.");
        }
        // 提取姓名
        for (int i = 0; i < infoArr.length; i++) {
            if (infoArr[i].indexOf("*") > -1) {
                continue;
            }
            if (infoArr[i].length() > 2) {
                if (infoArr[i].trim().indexOf(" ") > -1) {
                    Map<String, String> map = new HashMap<>();
                    map.put("name", Arrays.stream(ArrayUtil.sub(infoArr[i].split(" "), 0, infoArr[i].split(" ").length - 1)).collect(Collectors.joining(" ")));
                    map.put("sign", "P" + fNum);
                    fName.add(map);
                } else {
                    Map<String, String> map = new HashMap<>();
                    map.put("name", infoArr[i].trim());
                    map.put("sign", "P" + fNum);
                    fName.add(map);
                }
                fNum++;
            }
        }
        infoArr = pnrContent.replaceAll("\n", " ").split("SSR");
        // 提取婴儿
        for (int i = 0; i < infoArr.length; i++) {
            if (infoArr[i].length() > 0 && infoArr[i].indexOf("INF(") > -1) {
                Map<String, String> map = new HashMap<>();
                String[] infs = infoArr[i].split("INF\\(")[0].split("/");
                String[] infe = infoArr[i].split("INF\\(")[1].split("/");
                map.put("name", infs[infs.length - 1].trim() + "INF(" + infe[0]);
                map.put("sign", "INF");
                fName.add(map);
                isINF = true;
            }
        }
        // 提取证件号码及票号
        for (int i = 0; i < infoArr.length; i++) {
            // 证件提取（身份证）
            if (infoArr[i].length() > 0 && infoArr[i].indexOf("FOID") > -1) {
                Map<String, Object> map = new HashMap<>();
                map.put("isGj", false);
                map.put("sign", infoArr[i].split("NI")[1].split("/")[1].split(" ")[0]);
                fGJ.add(map);
                Map<String, Object> map2 = new HashMap<>();
                map2.put("card", Arrays.asList(infoArr[i].split("NI")[1].split("/")[0]));
                map2.put("sign", infoArr[i].split("NI")[1].split("/")[1].split(" ")[0]);
                fCard.add(map2);
            }
            // 婴儿出生日期
            if (infoArr[i].length() > 0 && infoArr[i].indexOf("INFT") > -1) {
                String[] infdate = infoArr[i].split("/P")[0].split(" ");
                Map<String, Object> map = new HashMap<>();
                map.put("isGj", false);
                map.put("sign", "INF");
                fGJ.add(map);
                Map<String, Object> map2 = new HashMap<>();
                map2.put("card", Arrays.asList(infdate[infdate.length - 1].trim()));
                map2.put("sign", "INF");
                fCard.add(map2);
            }
            // 证件提取（护照）
            if (infoArr[i].length() > 0 && infoArr[i].indexOf("DOCS") > -1) {
                isGJ = true;
                String[] temp = infoArr[i].replaceAll("\n", " ").replaceAll(" +", " ").split(" ");
                String tempStr = "";
                for (int j = 0; j < temp.length; j++) {
                    if (temp[j].length() > 4 && (temp[j].indexOf("/") > -1 || temp[j].indexOf(".") > -1)) {
                        if (temp[j].indexOf(".") > -1) {
                            break;
                        }
                        tempStr += temp[j];
                    }
                }
                Map<String, Object> map = new HashMap<>();
                map.put("isGj", true);
                map.put("sign", tempStr.split("/")[tempStr.split("/").length - 1]);
                fGJ.add(map);
                Map<String, Object> map2 = new HashMap<>();
                map2.put("card", Arrays.asList(ArrayUtil.sub(tempStr.split("/"), 0, 7)));
                map2.put("sign", tempStr.split("/")[tempStr.split("/").length - 1]);
                fCard.add(map2);
                /*
                for (var j in itemArray) {
                    if (itemArray[j].indexOf("/") > -1) {
                        var tempSign = itemArray[j].split("/")[itemArray[j].split("/").length - 1];
                        fCard.push({ card: itemArray[j].split("/").slice(1, itemArray[j].split("/").length - 1).join(" "), sign: tempSign });
                    }
                }
                */
            }
            // 票号提取
            if (infoArr[i].length() > 0 && infoArr[i].indexOf("TKNE") > -1) {
                String[] tempArr = infoArr[i].split(" ");
                for (int j = 0; j < tempArr.length; j++) {
                    if (tempArr[j].indexOf("/") > -1 && Pattern.matches("^.+/.+/.+$", tempArr[j])) {
                        if (tempArr[j].split("/")[0].indexOf("INF") > -1) {
                            Map<String, String> map = new HashMap<>();
                            map.put("no", tempArr[j].split("/")[0]);
                            map.put("sign", "INF");
                            fTno.add(map);
                        } else {
                            Map<String, String> map = new HashMap<>();
                            map.put("no", tempArr[j].split("/")[0]);
                            map.put("sign", tempArr[j].split("/")[2]);
                            fTno.add(map);
                        }
                    }
                }
            }
        }
        // CTCM项提取
        if (isGJ) {
            infoArr = pnrContent.split("CTCM");
            for (int i = 0; i < infoArr.length; i++) {
                if (i == 0) {
                    continue;
                }
                if (infoArr[i].length() > 0 && infoArr[i].indexOf("/P") > -1) {
                    String[] tempCt = infoArr[i].split("\n")[0].split(" ");
                    for (int ci = 0; ci < tempCt.length; ci++) {
                        if (tempCt[ci].indexOf("/P") > -1) {
                            Map<String, String> map = new HashMap<>();
                            map.put("mobile", tempCt[ci].split("/")[0]);
                            map.put("sign", tempCt[ci].split("/")[1]);
                            ctcm.add(map);
                        }
                    }
                }
            }
        } else {
            infoArr = pnrContent.replaceAll("\n", " ").split("CTCM");
            for (int i = 0; i < infoArr.length; i++) {
                if (i == 0) {
                    continue;
                }
                if (infoArr[i].length() > 0 && infoArr[i].indexOf("/P") > -1) {
                    Map<String, String> map = new HashMap<>();
                    map.put("mobile", infoArr[i].split("/")[0]);
                    map.put("sign", infoArr[i].split(" ")[0].split("/")[1]);
                    ctcm.add(map);
                }
            }
        }
        // 提取价格
        if (pnrContent.indexOf("FN/") > -1) {
            String[] ptemp;
            String[] itemp;
            String trInfo = pnrContent.replaceAll(" ", "");
            infoArr = trInfo.replaceAll("\nACNY", "ACNY").split("FN/"); // rtinfo.replace(/\n/g, " ").split("FN/");
            for (int i = 0; i < infoArr.length; i++) {
                if (infoArr[i].length() > 0 && (infoArr[i].indexOf("FCNY") > -1 || infoArr[i].indexOf("ECNY") > -1)) {
                    String FCNY = "0", CN = "0", YQ = "0", TAX = "0", SIGN = "";
                    if (infoArr[i].indexOf("\n") > -1) {
                        itemp = infoArr[i].split("\n")[0].split("/");
                    } else {
                        itemp = infoArr[i].split("/");
                    }
                    for (int j = 0; j < itemp.length; j++) {
                        String lastTwo = "";
                        if (itemp[j].length() - 2 >= 0) {
                            lastTwo = itemp[j].substring(itemp[j].length() - 2);
                        } else {
                            lastTwo = itemp[j];
                        }
                        if (itemp[j].indexOf("FCNY") > -1 || itemp[j].indexOf("ECNY") > -1) {
                            if (itemp[j].indexOf("FCNY") > -1) {
                                FCNY = itemp[j].replace("FCNY", "").split("\\.")[0].replaceAll("\\s", "");
                            } else {
                                FCNY = itemp[j].replace("ECNY", "").split("\\.")[0].replaceAll("\\s", "");
                            }
                        }
                        if (itemp[j].indexOf("TCNY") > -1 && lastTwo.indexOf("CN") > -1) {
                            CN = itemp[j].replace("TCNY", "").split("\\.")[0].replaceAll("\\s", "");
                        }
                        if (itemp[j].indexOf("TCNY") > -1 && lastTwo.indexOf("YQ") > -1) {
                            YQ = itemp[j].replace("TCNY", "").split("\\.")[0].replaceAll("\\s", "");
                        }
                        /*
                        if (itemp[j].indexOf("TCNY") > -1 && (lastTwo.indexOf("XT") > -1 || lastTwo.indexOf("XF") > -1)) {
                            TAX = itemp[j].replace("TCNY", "").split(".")[0].replace(/\s/g, "");
                        }
                        */
                        if (itemp[j].indexOf("XCNY") > -1) {
                            TAX = itemp[j].replace("XCNY", "").split("\\.")[0].replaceAll("\\s", "");
                        }
                        //if (/^[P][0-9]*.[+]./.test(itemp[j])) {
                        if (Pattern.matches("^[P][0-9]*", itemp[j])) {
                            SIGN = itemp[j].split(" ")[0];
                        }
                    }
                    Map<String, String> map = new HashMap<>();
                    map.put("FCNY", FCNY);
                    map.put("CN", CN);
                    map.put("YQ", YQ);
                    map.put("TAX", TAX);
                    map.put("SIGN", SIGN);
                    price.add(map);
                }
            }
        }
        // 整合信息
        for (int i = 0; i < fName.size(); i++) {
            String name = fName.get(i).get("name");
            List<String> card = new ArrayList<>();
            String no = "", fcny = "", cn = "", yq = "", tax = "", mobile = "";
            isGJ = false;
            for (int j = 0; j < fGJ.size(); j++) {
                if (fGJ.get(j).get("sign").equals(fName.get(i).get("sign"))) {
                    isGJ = (boolean) fGJ.get(j).get("isGj");
                    break;
                }
            }
            for (int j = 0; j < fCard.size(); j++) {
                if (fCard.get(j).get("sign").equals(fName.get(i).get("sign"))) {
                    card = (List<String>) fCard.get(j).get("card");
                    break;
                }
            }
            for (int j = 0; j < fTno.size(); j++) {
                if (fTno.get(j).get("sign").equals(fName.get(i).get("sign"))) {
                    no = fTno.get(j).get("no");
                    break;
                }
            }
            if (ctcm.size() > 0) {
                for (int j = 0; j < ctcm.size(); j++) {
                    if (ctcm.get(j).get("sign").equals(fName.get(i).get("sign"))) {
                        mobile = ctcm.get(j).get("mobile");
                        break;
                    }
                }
                if (mobile.length() == 0) {
                    mobile = ctcm.get(0).get("mobile");
                }
            }

            if (price.size() == 1) {
                fcny = price.get(0).get("FCNY");
                cn = price.get(0).get("CN");
                yq = price.get(0).get("YQ");
                tax = price.get(0).get("TAX");
            } else {
                for (int j = 0; j < price.size(); j++) {
                    if (price.get(j).get("SIGN").equals(fName.get(i).get("sign"))) {
                        fcny = price.get(j).get("FCNY");
                        cn = price.get(j).get("CN");
                        yq = price.get(j).get("YQ");
                        tax = price.get(j).get("TAX");
                        break;
                    }
                }
                if ("".equals(fcny)) {
                    for (int j = 0; j < price.size(); j++) {
                        if ("".equals(price.get(j).get("SIGN"))) {
                            fcny = price.get(j).get("FCNY");
                            cn = price.get(j).get("CN");
                            yq = price.get(j).get("YQ");
                            tax = price.get(j).get("TAX");
                            break;
                        }
                    }
                }
            }
            if (isGJ) {
                if (name.indexOf("INF") == -1) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("ftype", "1");
                    map.put("name", name);
                    map.put("card", card);
                    map.put("no", no);
                    map.put("fcny", fcny);
                    map.put("cn", cn);
                    map.put("yq", yq);
                    map.put("tax", tax);
                    map.put("mobile", mobile);
                    fare.add(map);
                } else {
                    Map<String, Object> map = new HashMap<>();
                    map.put("ftype", "2");
                    map.put("name", name);
                    map.put("card", card);
                    map.put("no", no);
                    map.put("fcny", fcny);
                    map.put("cn", cn);
                    map.put("yq", yq);
                    map.put("tax", tax);
                    map.put("mobile", mobile);
                    fare.add(map);
                }
            } else {
                if (name.indexOf("INF") == -1) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("ftype", "0");
                    map.put("name", name);
                    map.put("card", card);
                    map.put("no", no);
                    map.put("fcny", fcny);
                    map.put("cn", cn);
                    map.put("yq", yq);
                    map.put("tax", tax);
                    map.put("mobile", mobile);
                    fare.add(map);
                } else {
                    Map<String, Object> map = new HashMap<>();
                    map.put("ftype", "2");
                    map.put("name", name);
                    map.put("card", card);
                    map.put("no", no);
                    map.put("fcny", fcny);
                    map.put("cn", cn);
                    map.put("yq", yq);
                    map.put("tax", tax);
                    map.put("mobile", mobile);
                    fare.add(map);
                }
            }
        }
        return fare;
    }

    public static void main(String[] args) {
        String content = " 1.AMATA/JUNKO MR 2.KAMATA/MINAMO MS HT00Q9 \r 3.  NH950  D   SU16MAR  TAOHND HK2   1335 1745      SEAME -- 0 \r 4.TAO/T TAO/T 13789886961/QINGDAO YINYAN AVIATION SERVICES CO., LTD/LI/\r    /WEIQIANG   \r 5.REM 0208 0934 021XU/LIJUN\r 6.TL/1135/16MAR/TAO114 \r 7.SSR OTHS 1E MISSING SSR CTCM MOBILE OR SSR CTCE EMAIL OR SSR CTCR\r     NON-CONSENT FOR NH-1KAMATA/MINAMO MS   \r 8.SSR ADTK 1E TO NH BY 15FEB 2359 TAO TIME ZONE OTHERWISE WILL BE XLD  \r 9.SSR CTCM NH HK1 13969838955/P1   \r10.OSI NH CTCT13370882323   \r11.RMK 1A/64WNFV                                                               +    12.TAO114                                                                      -    ";
        getFare(content, "KS24D0");
    }

    /**
     * 解析RTKT原文
     *
     * @param content
     * @return
     */
    public static AirRtktRespDTO parseRtktText(String content) {
        AirRtktRespDTO airRtktRespDTO = new AirRtktRespDTO();
        airRtktRespDTO.setRtktContent(content);
        if (StrUtil.isNotBlank(content)) {
            String ticketType = null;
            String officeNo = "";
            String priceCode = "";
            String uatp = "";

            String[] arr = content.replaceAll(" +", " ").replaceAll("\\r\\n", "\n").split("\n");
            for (int ri = 0; ri < arr.length; ri++) {
                String[] tempArr = Arrays.stream(arr[ri].split(" ")).filter(p -> StrUtil.isNotBlank(p)).collect(Collectors.toList()).toArray(new String[0]);

                // 解析出票office、打票机号
                String tempStr = Arrays.stream(tempArr).collect(Collectors.joining(","));
                if (tempStr.indexOf("/") > 0 && StrUtil.isBlank(officeNo)) {
                    try {
                        String officeNoStr = tempStr.split("/")[tempStr.split("/").length - 1].replaceAll(" ", "");
                        officeNo = officeNoStr.substring(officeNoStr.length() - 6);
                        if (Pattern.matches("^[a-zA-Z]{3}[0-9]{3}$", officeNo.replaceAll(" ", ""))) {
                            airRtktRespDTO.setIssueOffice(officeNo);
                            airRtktRespDTO.setTicketVendingMachineNo(arr[ri + 1].replaceAll(" ", "").replace("DEV-", "".trim()));
                        } else {
                            officeNo = "";
                        }
                    } catch (Exception e) {
                        airRtktRespDTO.setIssueOffice("");
                        airRtktRespDTO.setTicketVendingMachineNo("");
                    }
                }

                // 解析票证类型
                if (ri == arr.length - 1) {
                    for (int typei = ri; typei > -10; typei--) {
                        if (arr[typei].replaceAll(" ", "").trim().length() > 0) {
                            String[] typeTemp = arr[typei].split(" ");
                            for (int tpi = typeTemp.length - 1; tpi >= 0; tpi--) {
                                if (typeTemp[tpi].length() > 0) {
                                    ticketType = typeTemp[tpi].replaceAll(" ", "").trim().trim();
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }

                // 解析票价级别、行李额
                String tempVoid = tempArr.length == 0 ? "" : tempArr[tempArr.length - 1];
                if (StrUtil.isNotBlank(tempVoid) && tempVoid.indexOf("VOID") > -1 && priceCode.length() == 0) {
                    tempArr = Arrays.stream(arr[ri - 1].split(" ")).filter(p -> StrUtil.isNotBlank(p)).collect(Collectors.toList()).toArray(new String[0]);
                    if (tempArr.length < 2) {
                        tempArr = Arrays.stream(arr[ri - 2].split(" ")).filter(p -> StrUtil.isNotBlank(p)).collect(Collectors.toList()).toArray(new String[0]);
                    }
                    try {
                        priceCode = StrUtil.trimStart(tempArr[tempArr.length - 2]);
                        if ("OK".equals(priceCode.substring(0, 2))) {
                            priceCode = priceCode.substring(2, priceCode.length() - 2);
                            airRtktRespDTO.setFareBasis(priceCode);
                        }
                        String baggageWeight = tempArr[tempArr.length - 1].replaceAll(" ", "");
                        if (baggageWeight.length() >= 3) {
                            baggageWeight = baggageWeight.substring(baggageWeight.length() - 3);
                            airRtktRespDTO.setBaggageWeight(baggageWeight);
                        }
                    } catch (Exception e) {
                        airRtktRespDTO.setFareBasis("");
                    }

                    if (tempStr.indexOf("CC,TP") > -1) {
                        uatp = "TP" + tempStr.split("CC,TP")[1].split(" ")[0];
                    }
                    if (tempStr.indexOf("CC,UP") > -1) {
                        uatp = "UP" + tempStr.split("CC,UP")[1].split(" ")[0];
                    }

                    if (StrUtil.isNotBlank(ticketType)) {
                        switch (ticketType) {
                            case "BSP":
                                if (uatp.startsWith("TP")) {
                                    airRtktRespDTO.setTicketType(BasicAirTicketTypeEnum.UATP.getType());
                                } else if (uatp.startsWith("UP")) {
                                    airRtktRespDTO.setTicketType(BasicAirTicketTypeEnum.GP.getType());
                                }
                                break;
                            case "BOP":
                                airRtktRespDTO.setTicketType(BasicAirTicketTypeEnum.BOP.getType());
                                break;
                        }
                    }
                }

                // 解析代理费
                String agencyFeeStr = null;
                String[] itemArr = content.replaceAll(" +", " ").replaceAll("\\r\\n", "\n").replaceAll("\n", " ").replaceAll("CNY0\\.00", "CNY").split(" ");
                String[] feeArr = Arrays.stream(itemArr).filter(p -> StrUtil.isNotBlank(p)).collect(Collectors.toList()).toArray(new String[0]);
                for (int j = feeArr.length - 1; j >= 0; j--) {
                    if (feeArr[j].indexOf("CNY") > -1) {
                        if ("CNY".equals(feeArr[j])) {
                            agencyFeeStr = feeArr[j + 2];
                            break;
                        } else {
                            agencyFeeStr = feeArr[j + 1];
                            break;
                        }
                    }
                }
                if (StrUtil.isNotBlank(agencyFeeStr)) {
                    airRtktRespDTO.setAgencyFee(new BigDecimal(agencyFeeStr));
                }
            }
        }
        return airRtktRespDTO;
    }

    /**
     * 获取rtkt票证类型
     *
     * @param ticketType
     * @return
     */
    public static Integer getTicketTypeByRtkt(String ticketType) {
        if (StrUtil.isNotBlank(ticketType)) {
            switch (ticketType) {
                case "BSP":
                    return BasicAirTicketTypeEnum.BSP.getType();
                case "BOP":
                    return BasicAirTicketTypeEnum.BOP.getType();
            }
        }
        return null;
    }

    /**
     * 获取detr票证类型
     *
     * @param payment
     * @return
     */
    public static Integer getTicketTypeByDetr(String payment) {
        if (StrUtil.isNotBlank(payment)) {
            if (payment.toUpperCase().contains("TP")) {
                return BasicAirTicketTypeEnum.UATP.getType();
            } else if (payment.toUpperCase().contains("UP")) {
                return BasicAirTicketTypeEnum.GP.getType();
            }
        }
        return BasicAirTicketTypeEnum.BSP.getType();
    }
}
